package com.sy.simpleegg.util

import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.SupplicantState
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.net.wifi.WifiNetworkSpecifier
import android.os.Build
import com.sy.simpleegg.app.App
import com.sy.simpleegg.ext.logFile

class WifiUtil(context: Context) {

    private var connectivityManager: ConnectivityManager? = null
    private var wifiManager: WifiManager? = null
    private var connectedCallback: ConnectedCallback? = null

    init {
        wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager?
        connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    }

    companion object{
        val mInstance by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
            WifiUtil(App.instance)
        }
    }

    fun setWifiConnectCallback(connectedCallback: ConnectedCallback){
        this.connectedCallback = connectedCallback
    }

    fun connectWifi(ssid: String, wifiPassword: String){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
            connectByNew(ssid, wifiPassword)
        }else{
            connectByOld(ssid, wifiPassword)
        }
    }

    private fun connectByOld(ssid: String, wifiPassword: String){
//        val ssid = scanResule.wifiName
        try {
            var isSuccess = false
            var configuration = isExist(ssid)
            if (configuration != null) {
                isSuccess = wifiManager!!.enableNetwork(configuration.networkId, true)
            } else {
                val wifiConfig = createWifiConfig(ssid, wifiPassword)
                val netId = wifiManager?.addNetwork(wifiConfig)
                isSuccess = wifiManager!!.enableNetwork(netId!!, true)
            }
//            logFile("Android10以下 wifi连接${if (isSuccess) "成功" else "失败"}")
//            if (isSuccess) {
//                connectedCallback?.connectSuccessed()
//            }else{
//                connectedCallback?.connectFailed()
//            }
        }catch (e: Exception){
            e.printStackTrace()
            logFile("连接wifi异常：${e.message}")
        }
    }

    private fun createWifiConfig(ssid: String, pwd: String?): WifiConfiguration?{
        try {
            val config = WifiConfiguration()
            config.allowedAuthAlgorithms.clear()
            config.allowedGroupCiphers.clear()
            config.allowedKeyManagement.clear()
            config.allowedPairwiseCiphers.clear()
            config.allowedProtocols.clear()
            config.SSID = "\"" + ssid + "\""
            if (pwd.isNullOrEmpty()) {
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
            } else {
                config.preSharedKey = "\"" + pwd + "\""
                config.hiddenSSID = true
                config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
                config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
                config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
                config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
                config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
                config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
                config.status = WifiConfiguration.Status.ENABLED
            }
            return config
        }catch (e: Exception){
            e.printStackTrace()
            logFile("创建wifi配置异常：${e.message}")
            return null
        }
    }

    @SuppressLint("NewApi")
    private fun connectByNew(ssid: String, wifiPassword: String?){
        try {
            val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
                .setSsid(ssid)
                .setWpa2Passphrase(wifiPassword!!)
                .build()

            val request = NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
                .setNetworkSpecifier(wifiNetworkSpecifier)
                .build()

            connectivityManager?.requestNetwork(
                request,
                object : ConnectivityManager.NetworkCallback() {
                    override fun onAvailable(network: Network) {
                        super.onAvailable(network)
                        logFile("Android10及以上 wifi连接成功")
                        connectedCallback?.connectSuccessed()
                    }

                    override fun onUnavailable() {
                        super.onUnavailable()
                        logFile("Android10及以上 wifi连接失败")
                        connectedCallback?.connectFailed()
                    }
                })
        }catch (e: Exception){
            e.printStackTrace()
            logFile("连接wifi异常2：${e.message}")
        }
    }

    @SuppressLint("MissingPermission")
    private fun isExist(ssid: String): WifiConfiguration?{
        val configurations = wifiManager!!.configuredNetworks
        configurations?.forEach {
            if (it.SSID == "\"" + ssid + "\""){
                return it
            }
        }
        return null
    }

    fun isWifiEnable(): Boolean{
        return wifiManager?.isWifiEnabled ?: false
    }

    fun openWifi(){
        if (!isWifiEnable()){
            wifiManager?.isWifiEnabled = true
        }
    }

    fun closeWifi(){
        wifiManager?.isWifiEnabled = false
    }

    @SuppressLint("MissingPermission")
    fun getScanResult(): MutableList<WifiConfiguration>? {
        return wifiManager?.configuredNetworks
    }

    fun startScanWifi(): Boolean? {
        return wifiManager?.startScan()
    }

    fun getConnectedWifiInfo(): WifiInfo? {
        return wifiManager?.connectionInfo
    }

    fun connectCompleteed(): Boolean{
        return getConnectedWifiInfo()?.supplicantState == SupplicantState.COMPLETED
    }

    interface ConnectedCallback{
        fun connectSuccessed()
        fun connectFailed()
    }
}